#include "ModelManager.h"

/* Constructor -------------------------------------------------------------- */

ModelManager::ModelManager(){}

ModelManager::ModelManager(int id)
{
	this->id = id;
}

/* Destructor --------------------------------------------------------------- */

ModelManager::~ModelManager(){}

/* Getters ------------------------------------------------------------------ */

vector<Mesh*> ModelManager::getModels()
{
	return this->models;
}

Mesh* ModelManager::getModel(EModel model)
{
	return this->models[model];
}

/* Setters ------------------------------------------------------------------ */

void ModelManager::setModels(vector<Mesh*> models)
{
	this->models = models;
}

/* Public Methods ----------------------------------------------------------- */

void ModelManager::addModel(Mesh *mesh)
{
	this->models.push_back(mesh);
}

//********************************************************************************************
// release the models
//
//********************************************************************************************
void ModelManager::release()
{
	for(unsigned int i=0;i<this->models.size();i++)
		models[i]->getMesh()->Release();
}

//********************************************************************************************
// obsolete -- draw the city model
//
//********************************************************************************************
void ModelManager::drawCity()
{
	D3DXMATRIX matTranslate;
	D3DXMatrixTranslation(&matTranslate, 0.0f, 0.0f, 0.0f);
    d3ddev->SetTransform(D3DTS_WORLD, &(matTranslate));

	for(DWORD j = 0; j < getModel(MODEL_CITY)->getNumMaterials(); j++)
    {
		d3ddev->SetMaterial(&getModel(MODEL_CITY)->getMaterial()[j]);
		getModel(MODEL_CITY)->getMesh()->DrawSubset(j);
    }
}

//********************************************************************************************
// draw a model
//
//********************************************************************************************
void ModelManager::drawModel(Drawable * drawableObject)
{
	D3DXMATRIX matTranslate;
	D3DXMATRIX matRotate;
	D3DXMATRIX mat;
	D3DXMatrixRotationY(&matRotate,drawableObject->getOrientation());

	D3DXMatrixTranslation(&matTranslate, drawableObject->getPosition()->getX(), 1.5f, drawableObject->getPosition()->getY());
    mat = matRotate*matTranslate;
	d3ddev->SetTransform(D3DTS_WORLD, &(mat));

	

	for(DWORD j = 0; j < getModel(drawableObject->getModel())->getNumMaterials(); j++)
    {
		d3ddev->SetMaterial(&getModel(drawableObject->getModel())->getMaterial()[j]);
		getModel(drawableObject->getModel())->getMesh()->DrawSubset(j);
    }

}

//********************************************************************************************
// init the models
//
//********************************************************************************************
void ModelManager::init() {
	loadModel(L"city.X"); //				MODEL_CITY,
	loadModel(L"car.X"); //					MODEL_CAR,
	loadModel(L"truck.X"); //				MODEL_TRUCK
	loadModel(L"TraficLightRed.X"); //		MODEL_TRAFICLIGHT_RED,
	loadModel(L"TraficLightOrange.X"); //	MODEL_TRAFICLIGHT_ORANGE,
	loadModel(L"TraficLightGreen.X"); //	MODEL_TRAFICLIGHT_GREEN,
	loadModel(L"Giveway.X"); //				MODEL_GIVEWAY,
	loadModel(L"Stop.X"); //				MODEL_STOP,
}

//********************************************************************************************
// load a model from .X file
//
//********************************************************************************************
void ModelManager::loadModel(LPCWSTR fileName){
	LPD3DXBUFFER bufMaterial;
	
	LPD3DXMESH mesh;           // define the mesh pointer
	D3DMATERIAL9* material;    // define the material object
	DWORD numMaterials;        // stores the number of materials in the mesh

    D3DXLoadMeshFromX(fileName,
                      D3DXMESH_SYSTEMMEM,
                      d3ddev,
                      NULL,
                      &bufMaterial,
                      NULL,
                      &numMaterials,
                      &mesh);

    // retrieve the pointer to the buffer containing the material information
    D3DXMATERIAL* tempMaterials = (D3DXMATERIAL*)bufMaterial->GetBufferPointer();

    // create a new material buffer for each material in the mesh
    material = new D3DMATERIAL9[numMaterials];

    for(DWORD i = 0; i < numMaterials; i++)
    {
        material[i] = tempMaterials[i].MatD3D;
        material[i].Ambient = material[i].Diffuse;
    }

	// add the loaded model
	addModel(new Mesh(mesh,
					  material,
					  numMaterials));
}